# encoding  :  utf-8 _*_
# @author   :  朱清闯
# @software :  PyCharm
# time      :  2022/2/8 21:59
from .models import User, VIP_Grade_CHOICE, USER_APPLICATION_STATUS_CHOICE, UserActivateApplication, UserVIPApplication
from .models import UserNicknameApplication, Notification, NOTIFICATION_STATUS_CHOICE, CustomerBankPointChangeLog
from .models import TRANSACTION_STATUS_CHOICE, WithdrawLog, RechargeLog, Sponsor
from .models import ClassGrade, UserOfClass
from rest_framework import serializers
from rest_framework.serializers import ListSerializer
from rest_framework_bulk.serializers import BulkListSerializer, BulkSerializerMixin
time_format = "%Y-%m-%d"
date_format = "%Y-%m-%d"


class MyListSerializer(ListSerializer):
    def update(self, instance, validated_data):
        for index, obj in enumerate(instance):
            self.child.update(obj, validated_data[index])
        return instance


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        list_serializer_class = MyListSerializer
        model = User
        fields = "__all__"


class UserModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["id", "username", "phone", "nickname", 'real_name', 'is_staff', 'bank_point', 'inviter_number',
                  'challenge_score', 'do_paper_count', 'is_teacher']


class UserSimpleModelSerializer(serializers.ModelSerializer):
    VIP_cn = serializers.SerializerMethodField(read_only=True)
    do_paper_count = serializers.SerializerMethodField(read_only=True)

    def get_VIP_cn(self, obj):
        VIP = obj.VIP
        return VIP_Grade_CHOICE[VIP][1]

    def get_do_paper_count(self, obj):
        count = obj.challenge.count()
        return count

    class Meta:
        model = User
        fields = ["id", "username", "phone", "nickname", "real_name", 'is_staff', 'bank_point', 'VIP',
                  'inviter_number', 'challenge_score', 'do_paper_count', 'VIP_cn', 'avatar', 'is_teacher', 'number']
        extra_kwargs = {'VIP_cn': {"read_only": True}, 'do_paper_count': {"read_only": True},
                        'avatar': {"read_only": True}}


class UserApplicationModelSerializer(serializers.ModelSerializer):
    user_info = serializers.SerializerMethodField(read_only=True)
    add_date = serializers.DateTimeField(format=time_format, required=False, read_only=True)
    status_info = serializers.SerializerMethodField(read_only=True)

    def get_status_info(self, obj):
        status = int(obj.status)
        return {'id': status, 'name': USER_APPLICATION_STATUS_CHOICE[status][1]}

    def get_user_info(self, obj):
        user_obj = obj.user
        is_active = user_obj.is_active

        if is_active:
            is_active_cn = "激活"
        else:
            is_active_cn = "禁用"
        return {'id': user_obj.id, 'real_name': user_obj.real_name, 'nickname': user_obj.nickname,
                'phone': user_obj.phone, 'is_active_cn': is_active_cn, 'is_teacher': user_obj.is_teacher}

    class Meta:
        model = UserActivateApplication
        fields = ['id', 'user_info', 'add_date', 'status_info', 'user', 'status']
        extra_kwargs = {'status_info': {"read_only": True}, 'add_date': {"read_only": True},
                        'user': {"write_only": True}, 'status': {"write_only": True}}


class UserVIPApplicationModelSerializer(serializers.ModelSerializer):
    user_info = serializers.SerializerMethodField(read_only=True)
    add_date = serializers.DateTimeField(format=time_format, required=False, read_only=True)
    grade_info = serializers.SerializerMethodField(read_only=True)
    status_info = serializers.SerializerMethodField(read_only=True)

    def get_grade_info(self, obj):
        grade = int(obj.VIP_grade)
        return {'id': grade, 'name': VIP_Grade_CHOICE[grade][1]}

    def get_user_info(self, obj):
        user_obj = obj.user
        VIP = user_obj.VIP
        vip_cn = VIP_Grade_CHOICE[VIP][1]
        return {'id': user_obj.id, 'real_name': user_obj.real_name, 'nickname': user_obj.nickname,
                'phone': user_obj.phone, 'VIP': VIP, 'VIP_cn': vip_cn}

    def get_status_info(self, obj):
        status = int(obj.status)
        return {'id': status, 'name': USER_APPLICATION_STATUS_CHOICE[status][1]}

    class Meta:
        model = UserVIPApplication
        fields = ['id', 'user_info', 'add_date', 'grade_info', 'user', 'status_info', 'status', 'VIP_grade']
        extra_kwargs = {'grade_info': {"read_only": True}, 'add_date': {"read_only": True},
                        'user': {"write_only": True}, 'status_info': {"read_only": True},
                        'status': {"write_only": True}, 'VIP_grade': {"write_only": True}}


class UserNicknameApplicationModelSerializer(serializers.ModelSerializer):
    user_info = serializers.SerializerMethodField(read_only=True)
    add_date = serializers.DateTimeField(format=time_format, required=False, read_only=True)
    status_info = serializers.SerializerMethodField(read_only=True)

    def get_user_info(self, obj):
        user_obj = obj.user
        VIP = user_obj.VIP
        vip_cn = VIP_Grade_CHOICE[VIP][1]
        return {'id': user_obj.id, 'real_name': user_obj.real_name, 'nickname': user_obj.nickname,
                'phone': user_obj.phone, 'VIP': VIP, 'VIP_cn': vip_cn}

    def get_status_info(self, obj):
        status = int(obj.status)
        return {'id': status, 'name': USER_APPLICATION_STATUS_CHOICE[status][1]}

    class Meta:
        model = UserNicknameApplication
        fields = ['id', 'user_info', 'add_date', 'nickname', 'user', 'status_info', 'status']
        extra_kwargs = {'add_date': {"read_only": True},
                        'user': {"write_only": True}, 'status_info': {"read_only": True},
                        'status': {"write_only": True}}


class NotificationModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Notification
        fields = "__all__"

    def to_representation(self, instance):
        data = super().to_representation(instance)
        data['add_date'] = instance.add_time.date()
        data['status_cn'] = NOTIFICATION_STATUS_CHOICE[instance.status][1]
        return data


class CustomerBankPointChangeLogModelSerializer(serializers.ModelSerializer):
    receiver_info = serializers.SerializerMethodField(read_only=True)
    operator_info = serializers.SerializerMethodField(read_only=True)

    def get_operator_info(self, obj):
        user_obj = obj.operator
        return {'id': user_obj.id, 'real_name': user_obj.real_name, 'nickname': user_obj.nickname,
                'phone': user_obj.phone}

    def get_receiver_info(self, obj):
        user_obj = obj.receiver
        return {'id': user_obj.id, 'real_name': user_obj.real_name, 'nickname': user_obj.nickname,
                'phone': user_obj.phone}

    class Meta:
        model = CustomerBankPointChangeLog
        fields = "__all__"

    def to_representation(self, instance):
        data = super().to_representation(instance)
        data['add_date'] = instance.add_time.date()
        return data


class WithdrawLogModelSerializer(serializers.ModelSerializer):
    user_info = serializers.SerializerMethodField(read_only=True)
    operator_info = serializers.SerializerMethodField(read_only=True)

    def to_representation(self, instance):
        data = super().to_representation(instance)
        if 'add_time' in data:
            data['add_date'] = data['add_time'][:10]
        data['status_cn'] = TRANSACTION_STATUS_CHOICE[data['status'] - 1][1]
        return data

    def get_user_info(self, obj):
        user_obj = obj.user
        return {'id': user_obj.id, 'real_name': user_obj.real_name, 'nickname': user_obj.nickname,
                'phone': user_obj.phone, 'bank_point': user_obj.bank_point, 'inviter_number': user_obj.inviter_number}

    def get_operator_info(self, obj):
        user_obj = obj.operator
        return {'id': user_obj.id, 'real_name': user_obj.real_name, 'nickname': user_obj.nickname,
                'phone': user_obj.phone, 'bank_point': user_obj.bank_point, 'inviter_number': user_obj.inviter_number}

    class Meta:
        model = WithdrawLog
        fields = "__all__"
        extra_kwargs = {'user_info': {"read_only": True}, 'operator_info': {"read_only": True}}


class RechargeLogModelSerializer(serializers.ModelSerializer):
    user_info = serializers.SerializerMethodField(read_only=True)
    operator_info = serializers.SerializerMethodField(read_only=True)

    def to_representation(self, instance):
        data = super().to_representation(instance)
        if 'add_time' in data:
            data['add_date'] = data['add_time'][:10]
        data['status_cn'] = TRANSACTION_STATUS_CHOICE[data['status'] - 1][1]
        return data

    def get_user_info(self, obj):
        user_obj = obj.user
        return {'id': user_obj.id, 'real_name': user_obj.real_name, 'nickname': user_obj.nickname,
                'phone': user_obj.phone, 'bank_pint': user_obj.bank_point, 'inviter_number': user_obj.inviter_number}

    def get_operator_info(self, obj):
        user_obj = obj.operator
        return {'id': user_obj.id, 'real_name': user_obj.real_name, 'nickname': user_obj.nickname,
                'phone': user_obj.phone, 'bank_pint': user_obj.bank_point, 'inviter_number': user_obj.inviter_number}

    class Meta:
        model = RechargeLog
        fields = "__all__"
        extra_kwargs = {'user_info': {"read_only": True}, 'operator_info': {"read_only": True}}


class SponsorModelSerializer(serializers.ModelSerializer):
    user_info = serializers.SerializerMethodField(read_only=True)

    def get_user_info(self, obj):
        user_obj = obj.user
        return {'id': user_obj.id, 'real_name': user_obj.real_name, 'nickname': user_obj.nickname,
                'phone': user_obj.phone, 'bank_pint': user_obj.bank_point, 'inviter_number': user_obj.inviter_number}

    class Meta:
        model = Sponsor
        fields = "__all__"
        extra_kwargs = {'user_info': {"read_only": True}}


# 用于序列化简单模型，不包含用户实体对象的
class ClassGradeSimpleModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = ClassGrade
        fields = ['id', 'name', 'graduated']


class ClassGradeModelSerializer(serializers.ModelSerializer):
    student_list = serializers.SerializerMethodField(read_only=True)
    teacher_list = serializers.SerializerMethodField(read_only=True)

    def get_student_list(self, obj):
        class_grade = ClassGrade.objects.get(id=obj.id)
        student_list = class_grade.user.filter(is_teacher=False)
        # result = UserSimpleModelSerializer(student_list, many=True).data
        result = student_list.values('id', 'username', 'number')
        return result

    def get_teacher_list(self, obj):
        teacher_list = obj.user.filter(is_teacher=True)
        # result = UserSimpleModelSerializer(teacher_list, many=True).data
        result = teacher_list.values('id', 'username', 'phone')
        return result

    class Meta:
        # list_serializer_class = MyListSerializer
        model = ClassGrade
        fields = "__all__"


class UserOfClassModelSerializer(serializers.ModelSerializer):
    add_date = serializers.DateTimeField(format=date_format, required=False, read_only=True)
    class_info = serializers.SerializerMethodField(read_only=True)
    user_info = serializers.SerializerMethodField(read_only=True)

    def get_user_info(self, obj):
        user_obj = obj.user
        return {'id': user_obj.id, 'username': user_obj.real_name, 'phone': user_obj.phone, 'number': user_obj.number}

    def get_class_info(self, obj):
        class_obj = obj.class_grade
        # dict = {False: '未毕业', True: '已毕业'}
        return {'id': class_obj.id, 'name': class_obj.name, 'graduated': class_obj.graduated}

    class Meta:
        model = UserOfClass
        fields = "__all__"
        list_serializer_class = MyListSerializer
